Skip to content

Cherry-pick for release/2.0: REST/OpenAPI/CLI/config-validation bug fixes#3516

Merged
RubenCerna2079 merged 17 commits intorelease/2.0from
dev/aaronburtle/Cherry-Pick-2.0
May 7, 2026
Merged

Cherry-pick for release/2.0: REST/OpenAPI/CLI/config-validation bug fixes#3516
RubenCerna2079 merged 17 commits intorelease/2.0from
dev/aaronburtle/Cherry-Pick-2.0

Conversation

@aaronburtle
Copy link
Copy Markdown
Contributor

Why make this change?

Closes #3515

Ports a set of REST, OpenAPI, CLI, and configuration-validation bug fixes from main to release/2.0 so the 2.0 release line includes:

  • Correct HTTP semantics for invalid If-Match headers on REST PUT/PATCH (now returns 400 instead of mishandling).
  • Cleaner OpenAPI documents — descriptive 404 message when filtering by a missing role, and removal of redundant _NoAutoPK / _NoPK schemas when request-body-strict is false.
  • Accurate config validation: corrected JSON-type mapping for int system types, alignment of parent/child config behavior during deserialization and startup, and improved entity validation logic.
  • Schema completeness: level-2 property on runtime.cache in dab.draft.schema.json.
  • CLI quality-of-life: consistent log labels matching ASP.NET Core's default console formatter, and clearer error messaging from dab validate when a logger is not yet available.

What is this change?

Cherry-picked PRs (chronological order on main):

How was this tested?

Existing and newly added unit/integration tests from each source PR.

aaronburtle and others added 9 commits May 5, 2026 23:24
## Why make this change?

Closes #3314

## What is this change?

Adds the `level-2` property, which is already a part of our object
model, to the `dab.draft.schema.json` file. Also adds `minimum: 1` to
`runtime.cache.ttl-seconds` to align schema validation with the runtime
enforcement that rejects values ≤ 0. The `level-2.provider` property is
kept as a plain string (no enum, no default) to match the nullable
string with `null` default in the object model.

## How was this tested?

- [ ] Integration Tests
- [ ] Unit Tests

## Sample Request(s)

N/A — schema-only change with no REST/GraphQL/CLI surface.

<!-- START COPILOT CODING AGENT TIPS -->
---

📍 Connect Copilot coding agent with [Jira](https://gh.io/cca-jira-docs),
[Azure Boards](https://gh.io/cca-azure-boards-docs) or
[Linear](https://gh.io/cca-linear-docs) to delegate work to Copilot in
one click without leaving your project management tool.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
(cherry picked from commit b301eeb)
…label on startup (#3307)

## Why make this change?

Closes #3269

## What is this change?

Align the CLI logger labels with the labels used in ASP.Net Core.
Downgraded internal plumbing message from `Information` to `Debug`

Add a test case to cover the changed behavior.

## How was this tested?

Added a test case to validate the new behavior.

(cherry picked from commit 75b8eec)
…n and startup (#3321)

## Why make this change?

Closes #3271

## What is this change?

Previously, child configs were defaulting to `throw` for their exception
behavior during deserialization, but parent configs correctly use
`ignore`. We align this behavior. Furthermore, during startup of the
engine we throw an exception if a child config itself can not be loaded,
halting startup, as would happen with the parent.

When a child config file exists but fails to load, a generic diagnostic
message is surfaced: `"Failed to load datasource file: {path}. Ensure
the file is accessible and contains a valid DAB configuration."` —
covering all failure modes including invalid JSON, IO errors, and
permission issues.

## How was this tested?

Added 2 new tests:
1. `ChildConfigWithMissingEnvVarsLoadsSuccessfully` — verifies that a
child config with unresolved `@env()` references loads successfully (env
vars saved and restored in `finally`; uses unique temp file path)
2. `ChildConfigLoadFailureHaltsParentConfigLoading` — verifies that a
child config file that exists but contains invalid JSON causes parent
config loading to fail (saves/restores `Console.Error` and disposes
`StringWriter` in `finally`; uses unique temp file path)

Updated `TestLoadRuntimeConfigSubFilesFails` to assert that non-existent
child config files are gracefully skipped (not treated as failures).

- [x] Unit Tests

---------

Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
(cherry picked from commit c014e52)
## Why make this change?

Closes #3261

## What is this change?

In the `RestController`, add descriptive messaging for `NotFound()` when
role is missing. Add a test case to cover this new behavior.

## How was this tested?

Test case added.

Manually verified the endpoint provided the correct response.

<img width="566" height="193" alt="image"
src="https://github.com/user-attachments/assets/e0549b70-b605-4ddc-a5d4-a107a91361ea"
/>

## Sample Request(s)

Can manually verify by going to this endpoint without a "foo" role
defined.

`https://localhost:5001/rest/openapi/foo`

---------

Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
(cherry picked from commit 5fa2bfc)
## Why make this change?

Closes #3397

## What is this change?

When `DeterminePatchPutSemantics` threw a `DataApiBuilderException` for
an invalid `If-Match` value, the exception was thrown before entering
`HandleOperation` and the `try-catch` block within. This is where we
convert `DataApiBuilderException` into structured JSON error response.
We therefore move the `DeterminePatchPutSemantics` call inside of the
`try-catch` block within `HandleOperation`, gating the function behind a
check of the operation type so that it only applies to `Upsert` and
`UpsertIncremental` operations.

## How was this tested?

Added a test for `Put` and a test for `Patch` to validate the new
behavior.

## Sample Request(s)

Any valid `Put` or `Patch` with headers using `If-Match` with a value
other than `*`

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
(cherry picked from commit 0cb58f0)
## Why make this change?

Closes #3268

## What is this change?

When `dab validate` or `dab start` encounters a config parsing error
(e.g. missing entities/autoentities), the CLI previously dumped the full
exception message and stack trace to stderr. This made the output noisy
and unhelpful. After this change, only a clean, descriptive validation
message is shown.

The key design changes:

- `TryParseConfig` is now a pure function that returns an `out string?
parseError` message on failure instead of writing to `Console.Error` or
`ILogger` internally. Error reporting is the caller's responsibility.
- `FileSystemRuntimeConfigLoader.TryLoadConfig` writes the `parseError`
to `Console.Error` (because config is parsed before the DI container and
logger are available, so the log buffer would never be flushed on a
parse failure) and sets an instance-scoped `IsParseErrorEmitted` flag so
CLI callers (`ConfigGenerator`) can avoid logging duplicate messages.
- `ConfigGenerator.IsConfigValid` now has an explicit early-return path
when config parsing fails (via `runtimeConfigProvider.TryGetConfig`),
using `IsParseErrorEmitted` to suppress duplicate output.
- `ValidateOptions.Handler` uses `LogError("Config is invalid.")`.
- Comments referencing which method emits the error to `Console.Error`
corrected to `TryLoadConfig` (not `TryParseConfig`).

## How was this tested?

* `ValidateConfigTests.cs` — Added
`TestValidateConfigWithNoEntitiesProducesCleanError` (new test verifying
clean error message, no stack traces).
* `EnvironmentTests.cs` — Updated
`FailureToStartEngineWhenEnvVarNamedWrong` to match the new single-line
clean stderr format.
* `EndToEndTests.cs` — Simplified assertions in
`TestExitOfRuntimeEngineWithInvalidConfig` (this test is Ignored but
updated for consistency).
* `RuntimeConfigLoaderTests.cs` — Updated
`FailLoadMultiDataSourceConfigDuplicateEntities` to assert
`loader.IsParseErrorEmitted` is true.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
(cherry picked from commit f2b4cbd)
…strict is false (#3325)

## Why make this change?

Closes #3260

## What is this change?

When request-body-strict is set to false, the OpenAPI document was still
generating separate _NoAutoPK and _NoPK component schemas for each
entity. These schemas only differ from the base entity schema by
excluding primary key fields, a distinction that is meaningless when the
request body already allows additional properties. This made the
generated OpenAPI document unnecessarily verbose and confusing for
consumers.

The `isRequestBodyStrict` flag is now threaded through `BuildPaths` and
`CreateOperations` so that POST/PUT/PATCH request body schema references
point to the base entity schema when strict mode is off. The
`CreateComponentSchemas` method now gates `_NoAutoPK` and `_NoPK` schema
generation on strict mode, and its XML documentation has been updated to
accurately describe both strict and non-strict behavior.

## How was this tested?

- [ ] Integration Tests
- [x] Unit Tests

Updated existing unit test
`RequestBodyStrict_False_OmitsRedundantSchemas` (renamed from
`RequestBodyStrict_False_AllowsExtraFields`) to verify that when
request-body-strict is false:
- `_NoAutoPK` and `_NoPK` component schemas are not generated.
- The base entity schema is still present.
- POST/PUT/PATCH operations reference the base entity schema (not
`_NoAutoPK` or `_NoPK`).

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
Co-authored-by: Anusha Kolan <anushakolan10@gmail.com>
(cherry picked from commit c860fc5)
## Why make this change?

Closes #3324

## What is this change?

Expand the enums for our json data type to include `integer`. Use this
new integer type in the system to json type map.

## How was this tested?

Existing test coverage.

---------

Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
(cherry picked from commit 062ddc6)
## Why make this change?

Closes #3267

## What is this change?

Alters the validation logic in the following way.

Is top-level config with data-source-files? (we call this a `Root`
config file)
├── YES
│ ├── Has datasource? → ValidateEntityPresence (same rules as non-root)
│   ├── No datasource but has entities/autoentities? → ERROR
│   └── No datasource, no entities → VALID (children provide everything)
│   └── For each child → ValidateNonRootConfig(child, filename)
│
└── NO (standalone or child config)
    ├── No datasource? → ERROR: "data source is required"
    └── Has datasource → ValidateEntityPresence

Note: A top-level config file without any children data-source files is
NOT considered a root. And an intermediary config file, ie: is a child,
that also has child configs is NOT a root. Only a top-level config with
children configs is a Root.

#### ValidateEntityPresence
Count resolved autoentities from AutoentityResolutionCounts
total = manual entities + resolved autoentities

total == 0? → ERROR: "No entities found"
total > 0 but autoentities discovered nothing? → WARN: "Autoentities
configured but none discovered"

No double messaging. If total is 0, only the error is recorded, not the
warning.

## How was this tested?

### Truth table — top-level config

Variables (`1` = present / non-empty, `0` = absent / empty):
- **DSF** — `data-source-files` present
- **DS** — `data-source` present
- **E** — manual `entities` count > 0
- **AE** — `autoentities` count > 0 (presence, *not* resolved count)

Path is determined by `IsRootConfig = (DSF == 1) && !IsChildConfig`.

| # | DSF | DS | E | AE | AE resolved | Path | Expected | Test |
|---|:---:|:--:|:-:|:--:|:-----------:|------|----------|------|
| 1 | 0 | 0 | 0 | 0 | — | Non-root | **Error**: "data source is
required" | `TestNonRootWithNoDataSourceProducesError` |
| 2 | 0 | 0 | 0 | 1 | — | Non-root | **Error**: "data source is
required" | _covered by #1 — DS check fires first_ |
| 3 | 0 | 0 | 1 | 0 | — | Non-root | **Error**: "data source is
required" | _covered by #1_ |
| 4 | 0 | 0 | 1 | 1 | — | Non-root | **Error**: "data source is
required" | _covered by #1_ |
| 5 | 0 | 1 | 0 | 0 | — | Non-root | **Error**: "No entities found" |
`TestNonRootWithDataSourceAndNoEntitiesProducesError` |
| 6a | 0 | 1 | 0 | 1 | 0 | Non-root | **Error**: "No entities found" |
`TestNonRootWithDataSourceAndAutoentitiesResolvingZeroProducesError` |
| 6b | 0 | 1 | 0 | 1 | >0 | Non-root | **Valid** |
`TestNonRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid` |
| 7 | 0 | 1 | 1 | 0 | — | Non-root | **Valid** |
`TestNonRootWithDataSourceAndEntitiesIsValid` |
| 8a | 0 | 1 | 1 | 1 | 0 | Non-root | **Valid** + **Warn** |
`TestNonRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning` |
| 8b | 0 | 1 | 1 | 1 | >0 | Non-root | **Valid** | _covered by #7 / #6b
combined_ |
| 9 | 1 | 0 | 0 | 0 | — | Root | **Valid** (children carry the load) |
`TestRootWithNoDataSourceAndNoEntitiesIsValid`,
`TestRootConfigWithNoDataSourceAndNoEntitiesParses` |
| 10 | 1 | 0 | 0 | 1 | — | Root | **Error**: "must not define entities
or autoentities" |
`TestRootWithNoDataSourceButAutoentitiesProducesError` |
| 11 | 1 | 0 | 1 | 0 | — | Root | **Error**: "must not define entities"
| `TestRootWithNoDataSourceButEntitiesProducesError` |
| 12 | 1 | 0 | 1 | 1 | — | Root | **Error** | _covered by #11_ |
| 13 | 1 | 1 | 0 | 0 | — | Root (with own DS) | **Error**: "No entities
found" | `TestRootWithDataSourceAndNoEntitiesProducesError` |
| 14a | 1 | 1 | 0 | 1 | 0 | Root (with own DS) | **Error**: "No entities
found" |
`TestRootWithDataSourceAndAutoentitiesResolvingZeroProducesError` |
| 14b | 1 | 1 | 0 | 1 | >0 | Root (with own DS) | **Valid** |
`TestRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid` |
| 15 | 1 | 1 | 1 | 0 | — | Root (with own DS) | **Valid** |
`TestRootWithDataSourceAndEntitiesIsValid` |
| 16a | 1 | 1 | 1 | 1 | 0 | Root (with own DS) | **Valid** + **Warn** |
`TestRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning` |
| 16b | 1 | 1 | 1 | 1 | >0 | Root (with own DS) | **Valid** | _covered
by #15 / #14b combined_ |

### Truth table — child config (validated when iterating
`root.ChildConfigs`)

Children are always treated as non-root regardless of their own
`data-source-files`.

| # | DS | E | AE | AE resolved | Expected | Test |
|---|:--:|:-:|:--:|:-----------:|----------|------|
| C1 | 0 | 0 | 0 | — | **Error** naming the child file: "data source is
required" | `TestChildWithNoDataSourceProducesNamedError` |
| C2 | 0 | * | * | — | **Error** naming the child file: "data source is
required" | _covered by C1_ |
| C3 | 1 | 0 | 0 | — | **Error** naming the child file: "No entities
found" | `TestChildWithDataSourceAndNoEntitiesProducesNamedError` |
| C4a | 1 | 0 | 1 | 0 | **Error** naming the child file: "No entities
found" |
`TestChildWithDataSourceAndAutoentitiesResolvingZeroProducesNamedError`
|
| C4b | 1 | 0 | 1 | >0 | **Valid** | _covered by C5 (resolved entities
behave the same as manual entities)_ |
| C5 | 1 | 1 | 0 | — | **Valid** | _implicitly via
`TestRootWithDataSourceAndEntitiesIsValid` setup_ |
| C6a | 1 | 1 | 1 | 0 | **Valid** + **Warn** naming the child file |
`TestChildWithEntitiesAndAutoentitiesResolvingZeroLogsNamedWarning` |
| C6b | 1 | 1 | 1 | >0 | **Valid** | _covered by C5_ |

### Other scenarios

| Scenario | Expected | Test |
|----------|----------|------|
| Connection-string error gates entity validation (no entity error fires
when DB unreachable) | `IsConfigValid == false` due to connection error
only | `TestValidateNonRootZeroEntitiesWithInvalidConnectionString` |
| Config with no entities parses cleanly (constructor no longer throws)
and `IsConfigValid` returns false without throwing | parse OK, validate
fails | `TestValidateConfigWithNoEntitiesProducesCleanError`
_(modified)_ |
| Root parses successfully without a data source | parse OK,
`IsRootConfig == true` |
`TestRootConfigWithNoDataSourceAndNoEntitiesParses` |
| Non-root with DS and no entities parses successfully | parse OK,
`IsRootConfig == false` |
`TestNonRootConfigWithDataSourceAndNoEntitiesParses` |
| Autoentities present but resolve to nothing — must not crash, must not
double-message with "No entities found" | no crash; only "No entities
found" if total = 0 | `ValidateAutoentitiesConfiguration` _(modified to
`isValidateOnly: true`)_ |

New tests:

`TestRootConfigWithNoDataSourceAndNoEntitiesParses` Root config (has
data-source-files) without datasource parses OK
`TestNonRootConfigWithDataSourceAndNoEntitiesParses` Non-root config
with datasource + no entities parses OK (validation catches it later)
`TestNonRootWithDataSourceAndNoEntitiesProducesError` Calls
ValidateDataSourceAndEntityPresence directly, error recorded
`TestNonRootWithNoDataSourceProducesError` No datasource, error with
"data source is required"
`TestNonRootWithDataSourceAndEntitiesIsValid` Datasource + entities, no
errors
`TestRootWithNoDataSourceAndNoEntitiesIsValid` Root with child, no own
datasource, valid
`TestRootWithNoDataSourceButEntitiesProducesError` Root with entities
but no datasource, error
`TestRootWithDataSourceAndEntitiesIsValid` Root with own datasource +
entities, valid
`TestChildWithDataSourceAndNoEntitiesProducesNamedError` Child with no
entities, error names the child file
`TestChildWithNoDataSourceProducesNamedError` Child with no datasource,
error names the child file
`TestNonRootWithDataSourceAndAutoentitiesResolvingZeroProducesError`
Non-root with only autoentities that resolve to 0
`TestNonRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid`
Non-root with only autoentities resolving > 0 entities
`TestNonRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning`
Non-root with manual entities + autoentities resolving 0
`TestRootWithNoDataSourceButAutoentitiesProducesError` Root with no
datasource but autoentities defined
`TestRootWithDataSourceAndNoEntitiesProducesError` Root with own
datasource and zero entities/autoentities
`TestRootWithDataSourceAndAutoentitiesResolvingZeroProducesError` Root
with own datasource and autoentities resolving 0
`TestRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid` Root
with own datasource and autoentities resolving > 0
`TestRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning` Root with
own datasource, manual entities, and autoentities resolving 0
`TestChildWithDataSourceAndAutoentitiesResolvingZeroProducesNamedError`
Child with autoentities-only resolving 0
`TestChildWithEntitiesAndAutoentitiesResolvingZeroLogsNamedWarning`
Child with manual entities + autoentities resolving 0

Modified tests:

`TestValidateConfigWithNoEntitiesProducesCleanError` Replaced main's
version (expected parse failure) with ours: parse succeeds,
IsConfigValid returns false
`ValidateAutoentitiesConfiguration` Changed to isValidateOnly: true,
asserts no crashes instead of zero errors

---------

Co-authored-by: Anusha Kolan <anushakolan10@gmail.com>
(cherry picked from commit c249436)
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This cherry-pick brings a set of REST/OpenAPI/CLI/config-validation fixes from main into release/2.0, improving HTTP semantics, generated OpenAPI output, and configuration parsing/validation behavior (including multi-config “root + data-source-files” scenarios).

Changes:

  • REST/OpenAPI: return correct 400 for invalid If-Match on PUT/PATCH; add descriptive 404 ProblemDetails for missing/invalid OpenAPI role requests; reduce OpenAPI schema verbosity when request-body-strict is false.
  • Config parsing/validation: align parent/child config handling, improve entity/autoentity validation after autoentity resolution, and refine error surfacing (clean parse errors when logger isn’t available).
  • CLI/schema: align CLI log labels with ASP.NET Core console formatter and add missing runtime.cache.level-2 + validation constraints to dab.draft.schema.json.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Service/Startup.cs Downgrades response-compression “enabled” log to Debug.
src/Service/HealthCheck/HealthCheckHelper.cs Guards datasource health checks when DataSource is null.
src/Service/Controllers/RestController.cs Moves If-Match semantics inside try/catch; returns descriptive 404 ProblemDetails for OpenAPI role lookups.
src/Service.Tests/UnitTests/RuntimeConfigLoaderJsonDeserializerTests.cs Updates parsing tests to assert parseError rather than logger invocations; clarifies child-file behavior docs.
src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs Adds integration test ensuring invalid If-Match returns 400.
src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs Adds integration test ensuring invalid If-Match returns 400.
src/Service.Tests/OpenApiDocumentor/StoredProcedureGeneration.cs Updates expected JSON types from numberinteger for int-like params.
src/Service.Tests/OpenApiDocumentor/RequestBodyStrictTests.cs Updates strict=false assertions to ensure redundant schemas are omitted and request bodies reference base schema.
src/Service.Tests/OpenApiDocumentor/ParameterValidationTests.cs Updates stored-proc parameter JSON type assertions to integer.
src/Service.Tests/OpenApiDocumentor/MissingRoleNotFoundTests.cs Adds integration test validating descriptive 404 ProblemDetails for missing/invalid OpenAPI roles.
src/Service.Tests/ModuleInitializer.cs Updates Verify settings to ignore newly added runtime-only RuntimeConfig members.
src/Service.Tests/Configuration/RuntimeConfigLoaderTests.cs Adds tests covering child config env-var ignore behavior and “existing but invalid child halts load”.
src/Service.Tests/Configuration/ConfigurationTests.cs Adapts tests to updated parsing/validation flows and nullable DataSource handling.
src/Core/Services/TypeHelper.cs Maps integral CLR types to JSON integer type.
src/Core/Services/OpenAPI/OpenApiDocumentor.cs Threads isRequestBodyStrict through path/op/schema generation and gates redundant schemas.
src/Core/Services/OpenAPI/JsonDataType.cs Introduces Integer JSON data type.
src/Core/Services/MetadataProviders/SqlMetadataProvider.cs Wraps non-DAB exceptions during DB connection validation as initialization errors.
src/Core/Services/MetadataProviders/MsSqlMetadataProvider.cs Tracks per-autoentity resolution counts for downstream validation.
src/Core/Services/MetadataProviders/CosmosSqlMetadataProvider.cs Adjusts for nullable DataSource (but still needs consistent null-safety).
src/Core/Configurations/RuntimeConfigValidator.cs Adds root/non-root entity presence validation after autoentity resolution; avoids GraphQL validation when datasource absent.
src/Core/Configurations/RuntimeConfigProvider.cs Updates parsing to new TryParseConfig(..., out parseError) overload (but still needs nullable-safe dereferences).
src/Config/RuntimeConfigLoader.cs Reworks parsing to return a clean parseError message instead of logging/printing stack traces.
src/Config/ObjectModel/RuntimeConfig.cs Makes DataSource nullable; adds root/child tracking and autoentity-resolution metadata; improves child-config load behavior.
src/Config/ObjectModel/MultipleCreateOptions.cs Removes trailing whitespace.
src/Config/ObjectModel/ChildConfigMetadata.cs Adds a record type for child-config metadata (validation support).
src/Config/FileSystemRuntimeConfigLoader.cs Emits clean parse errors to stderr and tracks whether they were already emitted.
src/Cli/CustomLoggerProvider.cs Aligns CLI log level labels to ASP.NET Core abbreviations and hardens color lookups.
src/Cli/ConfigGenerator.cs Adds clear CLI errors for root configs without datasources; suppresses duplicate parse-failure output (but needs nullable deref fixes).
src/Cli/Commands/ValidateOptions.cs Simplifies invalid-config message.
src/Cli.Tests/ValidateConfigTests.cs Adds extensive config-validation truth-table tests and verifies clean error paths.
src/Cli.Tests/UserDelegatedAuthRuntimeParsingTests.cs Adjusts for nullable DataSource with null-forgiveness where appropriate.
src/Cli.Tests/ModuleInitializer.cs Updates Verify ignore list for new runtime-only RuntimeConfig members.
src/Cli.Tests/EnvironmentTests.cs Updates assertions to match clean parse-error stderr output.
src/Cli.Tests/EndToEndTests.cs Updates end-to-end expectations to match new stderr/stdout behavior and nullable DataSource.
src/Cli.Tests/CustomLoggerTests.cs Adds test coverage for abbreviated log labels.
src/Cli.Tests/ConfigureOptionsTests.cs Adjusts for nullable DataSource with null-forgiveness where appropriate.
schemas/dab.draft.schema.json Adds runtime.cache.level-2 and enforces ttl-seconds minimum of 1.
Comments suppressed due to low confidence (1)

src/Core/Configurations/RuntimeConfigProvider.cs:200

  • RuntimeConfig.DataSource is now nullable, but this Initialize path still dereferences runtimeConfig.DataSource later (e.g., DatabaseType / ConnectionString). With nullable enabled + TreatWarningsAsErrors, this will produce nullable warnings and can also NRE if a config without data-source is passed. Add an explicit runtimeConfig.DataSource is null guard (with a clearer exception message) and/or use null-forgiveness after the guard so the code is both safe and compiles cleanly.
            if (string.IsNullOrEmpty(runtimeConfig.DataSource?.ConnectionString))
            {
                throw new ArgumentException($"'{nameof(runtimeConfig.DataSource.ConnectionString)}' cannot be null or empty.", nameof(runtimeConfig.DataSource.ConnectionString));
            }

Comment thread src/Config/ObjectModel/RuntimeConfig.cs
Comment thread src/Cli/ConfigGenerator.cs
Comment thread src/Core/Services/MetadataProviders/CosmosSqlMetadataProvider.cs
Copy link
Copy Markdown
Collaborator

@Aniruddh25 Aniruddh25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have approved the PR since its mostly cherry picks, but the comments from Copilot are pretty high importance. Did we resolve those comments when merged in main?

@aaronburtle
Copy link
Copy Markdown
Contributor Author

I have approved the PR since its mostly cherry picks, but the comments from Copilot are pretty high importance. Did we resolve those comments when merged in main?

Comments #2 and #3 are not valid, but comment #1 was, its a 1 line fix, will send to main separately.

@RubenCerna2079 RubenCerna2079 merged commit 6925175 into release/2.0 May 7, 2026
12 checks passed
@RubenCerna2079 RubenCerna2079 deleted the dev/aaronburtle/Cherry-Pick-2.0 branch May 7, 2026 01:47
@github-project-automation github-project-automation Bot moved this from Review In Progress to Done in Data API builder May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants